CodeForge
Visual C++ Class Designer & Code Generator for Unreal Engine 5
Describe a gameplay type in a node graph or a JSON file. CodeForge checks it against the rules UnrealHeaderTool and the compiler enforce, then writes the header and source into your module, with replication, RPCs, delegates and interface overrides already wired.
v0.5.0 · UE 5.5–5.81 Overview
CodeForge is an editor plugin. A definition (a CodeForge Blueprint asset, or an entry in a .codeforge.json file) describes one C++ type: its parent, members, specifiers, network behaviour and function bodies. CodeForge turns it into a compile-ready .h/.cpp pair in the module you choose and keeps it in sync as the definition changes.
2 What's New in 0.5.0
| Area | New |
|---|---|
| Lift to C++ | Turn a Blueprint into a C++ base class: variables, functions (BlueprintNativeEvents with a C++ stub, overridden by the Blueprint's graphs), dispatchers, custom events, and the Blueprint structs and enums they use move to generated C++. The Blueprint is reparented and every reference redirected, with verification, automatic rollback, undo and backups (§ Lift to C++). |
| Definition files | Every generated type keeps its definition as <Name>.codeforge.json next to its header, so definitions are reviewed, diffed and merged as text; -Schema=<folder> regenerates from them (§ JSON Definitions). |
| Emberwood | A new sample game: a small action RPG whose 20 gameplay types (hero, shades, a boss, shrines, pickups, a light component, a progress subsystem, the game mode, a Slate HUD, structs, enums, an interface, a save game) are one definition file, with a PIE test that plays it on autopilot. |
| Editor | Graphs are laid out in columns grouped by kind (on first open and with Auto Layout); members added from the right-click menu arrive wired to the type node; Fix: entries say what they do (Rename to bLit); a new type reports that it needs a build and restart instead of offering Live Coding. |
| Fixes | C++ keywords are matched case-sensitively (For, Default and Class are valid names). Definition files use LF line endings on every platform. Long validation messages wrap instead of widening nodes. |
0.3.0 added:
| Area | New |
|---|---|
| Language | Interfaces (with automatic overrides in implementing classes), delegates (4 kinds, 0–9 params), 9 new parents incl. subsystems, SaveGame, data assets, function libraries and custom C++ parents; class options (Abstract, NotBlueprintable, Config, DisplayName, spawnable components); struct parents (FTableRowBase); bitflag enums; BlueprintImplementableEvent, static, CallInEditor, parameter defaults, member access levels; Transient/Config/AdvancedDisplay properties; doc comments from descriptions. |
| Workflow | New Type wizard with 23 archetypes; JSON import/export with a JSON Schema; -run=CodeForge commandlet; Python/Editor Utility library; Content Browser and Tools menu actions; project-file refresh and Open C++; syntax-coloured preview with on-disk status; auto-fix from the graph. |
| Output | Clean, deterministic formatting; per-file template overrides; meta and category quoting; Public/Private layout for every module; no overwriting of hand-written files. |
| Correctness | Dozens of UHT/compiler rules validated up front (shadowing, events, statics, interfaces, replication, enum ranges). Graph and asset can no longer drift apart. Undo/redo refreshes preview and validation. |
| Sample | The Arena: a playable game whose 16 gameplay types are all generated, plus a PIE test that plays it. |
3 Installation
- Copy the plugin into
Plugins/of a C++ project. A Blueprint-only project needs one C++ class first (Tools → New C++ Class). - Regenerate project files and build, or open the project and let the editor build the plugin.
- Check Edit → Plugins → Editor → CodeForge.
4 Quick Start
- Create: Content Browser → Add → CodeForge → CodeForge Blueprint. Pick Replicated Actor, your module, an optional sub-folder, and keep Starter content on.
- Name it without a prefix:
BeaconbecomesABeacon. - Design: right-click the graph to add properties, functions, RPCs and delegates. The preview on the right updates as you edit.
- Generate: click Generate. New files refresh the IDE project. Build or use Live Coding.
To see a complete game first, open the Arena sample (§ Arena) or use Tools → CodeForge → Import Sample Pack in your own project.
5 Architecture
| Layer | Module | Key types |
|---|---|---|
| Data model & validation | CodeForgeRuntime | UCodeForgeBlueprint, FCodeForgePropertyDef, FCodeForgeFunctionDef, FCodeForgeRPCDef, FCodeForgeDelegateDef, FCodeForgeEnumEntryDef, type options |
| Template engine | CodeForgeRuntime | FCodeForgeTemplateEngine, FCodeForgeTemplateContext |
| Generator | CodeForgeEditor | FCodeForgeGenerator, CodeForgeBatch, FCodeForgeModuleScanner, FCodeForgeChangeDetector |
| I/O & automation | CodeForgeEditor | FCodeForgeSchema (JSON), UCodeForgeCommandlet, UCodeForgeEditorLibrary |
| Editor UI | CodeForgeEditor | FCodeForgeAssetEditor, UCodeForgeEdGraph, node classes, SCodeForgeNewAssetWizard, menu actions |
6 Definitions
A definition is the single source of truth for a type. In the editor it is a CodeForge Blueprint asset; on disk it can also be a .codeforge.json entry (§ JSON). Both carry the same fields.
Naming and prefixes
Enter the name without its Unreal prefix. CodeForge adds the right one, and keeps a prefix you already typed instead of doubling it.
| Kind | Prefix | Name | Generated type |
|---|---|---|---|
| Actor-derived class | A | Turret | ATurret |
| Other class | U | ScoreSubsystem | UScoreSubsystem |
| Struct | F | WeaponRow | FWeaponRow |
| Enum | E | PickupType | EPickupType |
| Interface | U / I | Damageable | UDamageable / IDamageable |
Where files go
Source/<Module>/Public/<SubDirectory>/<Name>.h and Source/<Module>/Private/<SubDirectory>/<Name>.cpp. Enums are header-only. Any game or plugin module of the project can be the target.
7 The Node Graph
Each asset has one type node (Class, Struct, Enum or Interface). Member nodes wire into it. Only members connected to the type node are generated, so a disconnected node is a quick way to park an idea.
| Node | Connects to | Holds |
|---|---|---|
| Property | Class, Struct | One FCodeForgePropertyDef |
| Function | Class, Interface | One FCodeForgeFunctionDef |
| RPC | Networked classes (actors and components) | One FCodeForgeRPCDef |
| Delegate | Class | One FCodeForgeDelegateDef |
Right-click empty space for the add menu; the type nodes are offered only while the graph has none. Node badges show validation results; right-click a node for its Fix: entries (§ Auto-Fix).
8 Code Generation
- Generate validates first and refuses to write on errors.
- Files without the
// Generated by CodeForge - DO NOT EDITmarker are never replaced without confirmation. - Batches (folder, multi-selection, commandlet) generate enums → structs → interfaces → classes, and resolve interfaces from the batch first, then from assets.
- Creating new files triggers an IDE project refresh (setting). Changing only function bodies can go through Live Coding automatically; layout or reflection changes prompt, because they need a rebuild.
- Output is normalised: LF line endings, four-space indentation, no trailing whitespace, a single final newline. The same definition always produces the same bytes.
9 Classes
Parents
| Family | ClassType values | Notes |
|---|---|---|
Actors (A) | Actor, Pawn, Character, GameModeBase, GameStateBase, PlayerController, PlayerState, HUD | Generated constructor; bReplicates = true when replicated |
| Components | ActorComponent, SceneComponent | SetIsReplicatedByDefault(true); spawnable from Blueprints by default |
| Objects | Object, DataAsset, PrimaryDataAsset, SaveGame, GameInstance | |
| Subsystems | GameInstanceSubsystem, WorldSubsystem, LocalPlayerSubsystem, EngineSubsystem | Override Initialize/Deinitialize as functions |
| Libraries | BlueprintFunctionLibrary | All functions must be static (validated) |
| Custom | Custom + Custom Parent Class/Include/Family | Any C++ parent, e.g. AStaticMeshActor from Engine/StaticMeshActor.h |
Class options
| Option | Emits |
|---|---|
| Abstract | Abstract |
| Blueprintable / Blueprint Type | Blueprintable, or NotBlueprintable, BlueprintType |
| Spawnable Component | ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) |
| Display Name | meta=(DisplayName="...") |
| Config Name / Default Config | Config=Game, DefaultConfig |
Also per class: description (doc comment), constructor body, extra source includes, implemented interfaces and their function bodies.
Properties
Edit flags (VisibleAnywhere, EditAnywhere, EditDefaultsOnly, EditInstanceOnly), Blueprint access, Replicated / RepNotify with condition and OnRep_ body, ExposeOnSpawn, SaveGame, Transient, Config, AdvancedDisplay, free meta tags, an include path for the type, a default value, a description, and access level. Category is written only when the property is visible to the editor or Blueprints, which avoids a UHT warning.
/** Current health, replicated to clients. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, ReplicatedUsing=OnRep_Health, Category="Arena")
float Health = 100.f;
Functions
BlueprintCallable, BlueprintPure (requires an output), const, BlueprintNativeEvent (declares and defines _Implementation), BlueprintImplementableEvent (no body), static, CallInEditor, Exec console commands, plain C++ helpers (bUFunction off), virtual and override, parameter defaults, meta tags and access levels. Overrides of engine functions (BeginPlay, Tick, Initialize) are plain virtual ... override, never UFUNCTION.
RPCs & replication
Server, Client and NetMulticast RPCs, reliable or unreliable. Server RPCs get WithValidation and a _Validate stub. Replicated properties produce GetLifetimeReplicatedProps with DOREPLIFETIME_CONDITION.
void UArenaHealthComponent::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UArenaHealthComponent, Health, COND_None);
}
void UArenaHealthComponent::ServerRequestHeal_Implementation(float Amount)
{
Heal(Amount);
}
Delegates
Dynamic multicast (Blueprint events, BlueprintAssignable), dynamic, multicast and single, with 0–9 parameters. Each delegate generates its signature (F<Name>Signature) above the class and a member.
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnHealthChangedSignature, float, NewHealth, float, Delta);
...
UPROPERTY(BlueprintAssignable, Category="Arena")
FOnHealthChangedSignature OnHealthChanged;
10 Interfaces
An Interface definition generates the UINTERFACE and its I class. Blueprintable interfaces take BlueprintNativeEvent/BlueprintImplementableEvent functions; non-Blueprintable ones take virtual C++ functions. Validation enforces UHT's rules for both.
A class that lists the interface under Interfaces inherits it and gets the overrides automatically: _Implementation for events, virtual ... override otherwise. Bodies come from Interface Function Bodies; callers use IArenaDamageable::Execute_ApplyArenaDamage(Target, ...).
11 Structs
USTRUCT(BlueprintType) with properties, an optional parent struct and its include (FTableRowBase + Engine/DataTable.h for Data Table rows). Blueprint-visible struct members must be public, and replication flags aren't allowed on struct members. Both are validated.
12 Enums
enum class E... : uint8 with display names, hidden entries, doc comments and explicit values (validated to fit uint8). Bitflags enums write power-of-two values, meta=(Bitflags, UseEnumValuesAsMaskValuesInEditor="true") and ENUM_CLASS_FLAGS, ready for a Bitmask property.
13 New Type Wizard
Opens when you create a CodeForge Blueprint. Choose one of 23 archetypes:
| Gameplay | Actor, Replicated Actor, Pawn, Character, Actor Component, Scene Component |
|---|---|
| Framework | Game Mode, Game State, Player Controller, Player State, HUD, Game Instance |
| Systems | Game Instance Subsystem, World Subsystem, Function Library, Object, Interface |
| Data | Primary Data Asset, Save Game, Struct, Data Table Row, Enum, Bitflags Enum |
Then pick the target module (every module in the project is listed) and sub-folder, and decide whether to add starter content: typical members for that archetype, such as a replicated Health with OnRep and a server RPC, or an Exec cheat on a player controller. Every archetype is compiled in the test suite with and without starter content.
14 Asset Editor
| Toolbar | Does |
|---|---|
| Generate | Validate and write the files, then refresh the project and offer Live Coding |
| Fix All | Apply every automatic fix (undoable) |
| Open C++ | Open the generated header and source in your IDE |
| Advanced | Show the advanced specifier set in node details |
The Details panel edits the selected node, or the type itself when nothing is selected. Fields that the graph owns are hidden there, so the two can't disagree. Undo and redo cover graph and Details edits and refresh validation and preview.
Code Preview
Shows the exact header and source that Generate will write, syntax-coloured, plus a status chip comparing it with the disk:
| Status | Meaning |
|---|---|
| NOT GENERATED YET | No files on disk |
| UP TO DATE | Disk matches the preview |
| CHANGED - GENERATE TO UPDATE | The definition changed since the last generation |
| HAND-WRITTEN FILE IN THE WAY | A file of that name exists without the CodeForge marker |
| MODULE NOT FOUND | The target module isn't in this project |
| FIX ERRORS | Validation errors block generation |
Menus
- Content Browser, right-click CodeForge assets (multi-select works): Generate C++, Validate (results in the CodeForge Message Log), Export Schema..., Open Generated C++.
- Tools → CodeForge: Import Schema..., Generate All CodeForge Assets, Import Sample Pack, CodeForge Documentation.
15 Plugin Settings
Project Settings → Plugins → CodeForge:
| Setting | Default | Effect |
|---|---|---|
| Default Module Target / Sub Directory | Pre-filled for new assets | |
| Custom Template Path | Folder with template overrides (§ Templates) | |
| Auto Live Coding On Behavioral Change | on | Run Live Coding when only function bodies changed |
| Regenerate Project Files On New Files | on | Refresh the IDE project when generation creates files |
| Open Generated Files In IDE | off | Open the files after each generation |
| Write Definition Files | on | Write each definition as <Name>.codeforge.json next to its header (§ JSON Definitions) |
| Show Preview By Default | on | Code Preview tab in new editor windows |
| Node colours, fonts, brand colours | Graph appearance |
16 Lift to C++
Lift to C++ turns an existing Blueprint into a C++ base class. It generates a C++ parent that holds the Blueprint's variables, functions, event dispatchers and custom events, plus C++ versions of the Blueprint structs and enums they use. After a build it reparents the Blueprint onto that class and redirects every reference. Each step is verified, and the whole change can be undone.
- Right-click a Blueprint → Lift to C++..., or use the Lift to C++ button in the Blueprint editor toolbar.
- The dialog lists every member with its C++ declaration, and explains anything that stays. Name the class (default: the Blueprint's name without
BP_, plusBase), choose the module and folder, and untick members you want to keep in the Blueprint. - CodeForge saves the definitions to
<Blueprint folder>/CodeForge, generates the C++, adds missing module dependencies toBuild.csand refreshes the IDE project. - Build and restart. At startup CodeForge offers Complete Now; the context menu and the toolbar (Complete Lift) work too.
What moves, what stays
| Blueprint | C++ |
|---|---|
| Variable | UPROPERTY with the same name and the same reflected type, keeping edit and Blueprint access, replication, SaveGame, Transient, AdvancedDisplay, Expose on Spawn, category, tooltip and meta. The current value becomes the initializer. |
| Event dispatcher | Dynamic multicast delegate and a BlueprintAssignable, BlueprintCallable property |
| Custom event | BlueprintImplementableEvent; the Blueprint's node becomes an override with the same links, so C++ can call it |
| Function | BlueprintNativeEvent with a C++ _Implementation stub to move the logic into (or BlueprintImplementableEvent: untick C++ body). The function graph becomes the override, with its nodes and links. Input defaults become default arguments; outputs become reference parameters and ReturnValue the return value |
| Blueprint struct they use | USTRUCT(BlueprintType) with readable member names, replaced in every Blueprint that uses it |
| Blueprint enum they use | enum class UENUM with the same values and display names, replaced everywhere, Switch on Enum and Select nodes included |
The following stay in the Blueprint, each with its reason:
- names that aren't C++ identifiers;
- variables typed with a Blueprint class or a bitmask Blueprint enum;
- RepNotify, Config, Field Notify and Expose-to-Cinematics variables;
- replicated, Call In Editor and overriding custom events;
- RepNotify functions, Call In Editor and thread-safe functions, pure functions without an output, pass-by-reference inputs, and input defaults C++ can't hold (texts, vectors);
- anything whose C++ wouldn't compile, such as a parameter named like a variable.
Graph logic stays in the Blueprint: function graphs become overrides of their C++ declarations.
Complete, verification and undo
Complete Lift to C++ checks that the compiled class and structs match the Blueprint, backs up the affected assets, then, as one undo transaction:
- redirects the Blueprint structs and enums everywhere: variables, parameters, Make/Break, Switch and Select nodes, split pins and defaults;
- reparents the Blueprint and removes its own copies of the lifted members;
- turns the lifted custom events and functions into overrides;
- points other Blueprints' references at the C++ members;
- compiles everything affected.
It then verifies:
- the parent is the new class;
- nothing lifted is left in the Blueprint;
- everything compiles;
- no pin link was lost;
- every lifted function overrides its C++ declaration;
- no replaced struct or enum is still in use;
- class defaults and per-instance values in maps are unchanged.
Scripting: analyze_lift, lift_to_cpp, complete_lift, restore_lift_backup (Python) and -Lift= / -CompleteLift= (commandlet). The sample project's /Game/CodeForgeSamples/Lift/BP_Beacon is ready to try. Full guide: docs/lift-to-cpp.md.
17 JSON Definitions
*.codeforge.json files hold any number of definitions with the same fields as the assets. Keys are the C++ field names, and defaults are omitted on export. Use them for source control, code review, CI and sharing. Schema/codeforge.schema.json gives editors completion and validation; an automation test keeps it in step with the data model.
{
"SchemaVersion": 1,
"Definitions": [
{ "ClassName": "HealthComponent", "ClassType": "ActorComponent",
"ModuleTarget": "MyGame", "bReplicated": true,
"Properties": [ { "Name": "Health", "Type": "float", "DefaultValue": "100.f",
"bReplicated": true, "bRepNotify": true } ] }
]
}
Import: Tools → CodeForge → Import Schema.... Export: right-click assets → Export Schema.... Invalid enum values fail the import and name the field; unknown keys are logged and ignored. The full field reference is in docs/json-schema.md.
Definition files next to the code. Generating a type also writes its definition as <Name>.codeforge.json beside the header (Turret.h, Turret.codeforge.json). The definition travels in the same commit and pull request as its code, as one small file per type with deterministic output, so it diffs line by line and merges as text. Assets are binary and can't be merged: resolve a conflict in the JSON, then run -run=CodeForge -Schema=Source/MyGame -Generate (code) or -Import=Source/MyGame (assets). Both read every *.codeforge.json under a folder. A JSON file CodeForge didn't write is never overwritten without asking. Turn the files off with the Write Definition Files setting.
18 Commandlet & CI
UnrealEditor-Cmd.exe MyGame.uproject -run=CodeForge -Schema=Design/Game.codeforge.json -Generate -unattended -nullrhi
| Option | Meaning |
|---|---|
-Import=<file> -Dest=/Game/Path | Create or update assets from a file |
-Schema=<file> | Use a file's definitions directly (no assets) |
-Source=/Game/Path | Use the CodeForge assets under a folder |
-Validate / -Generate | Validate / validate and write C++ |
-ProjectDir=<dir>, -Overwrite | Target another project; replace hand-written files |
-Export=<file> | Write the definitions to a file |
Exit code 0 on success, 1 on any error. Because the output is deterministic, git diff --exit-code -- Source after generation is a reliable "generated code is up to date" check.
19 Python
import unreal
lib = unreal.CodeForgeEditorLibrary
result = lib.generate_folder("/Game/Design", False)
if not result.success:
unreal.log_error(result.message)
result, header, source = lib.preview_code(unreal.load_asset("/Game/Design/Turret"))
assets, error = lib.import_schema("D:/Design/Game.codeforge.json", "/Game/Design", True)
lib.apply_auto_fixes(assets[0])
Also: generate_code, generate_code_in_project, validate_definition, export_schema, find_definitions. Operations return CodeForgeScriptResult (success, message, files), so a failure always carries its reason. The same functions are available to Editor Utility Blueprints under CodeForge | Editor.
20 Validation Rules
| Area | Checks |
|---|---|
| Names | Valid identifiers; no C++ keywords or engine-reserved names; no duplicates among members; b prefix on bools (warning) |
| Specifiers | ReadWrite + ReadOnly conflict; BlueprintPure needs an output; events must not be virtual; private members can't be events; Blueprint-visible private members get AllowPrivateAccess; Config properties need a config name |
| Kinds | Function libraries need static functions; interface content rules; RPCs only on actors and components; custom parents need a class and an include |
| Networking | RepNotify without Replicated; replicated members on a non-replicated class; replication on struct members or non-replicating object types; defaults on RPC parameters |
| C++ | Overrides marked UFUNCTION; parameters shadowing class, parent or interface members (C4458 is an error in UE builds); enum values outside uint8; non-power-of-two bitflags; more than nine delegate parameters; empty enums and types |
21 Auto-Fix
Some findings carry a fix. In the graph, right-click the flagged node and choose Fix: <message>, or click Fix All. Fixes are transactions, so Undo reverts them.
| Fix | For |
|---|---|
Rename to bName | Bool without the b prefix |
| Enable Replicated | Property with RepNotify but not Replicated |
| Enable class replication | Replicated members on a class that doesn't replicate |
| Remove replication flags | Struct members marked for replication |
| Drop UFUNCTION | Overrides of parent functions |
Fix All repeats until nothing fixable is left, because one fix can uncover another (replicating a property reveals that the class must replicate). Python: apply_auto_fixes(asset).
22 Templates
Output comes from .cft templates in Plugins/CodeForge/Content/Templates. Set Custom Template Path to a project folder and copy only the files you want to change. Lookup is per file, and anything you don't override falls back to the built-ins.
| Syntax | Meaning |
|---|---|
{{Name}} | Value |
{{#if Name}}...{{/if}} | Conditional section |
{{#each Name}}...{{/each}} | Repeated section |
{{> name}} | Include another template |
{{! comment}} | Template comment |
Tags alone on a line vanish with their line, and the output is normalised afterwards. Keep // Generated by CodeForge - DO NOT EDIT in copyright_header.cft: it is how CodeForge recognises its own files. The values available to each template are listed in docs/templates.md.
23 Module Layout
Generation targets are the game modules declared in the .uproject (Source/<Module>) and the modules of project plugins, including nested ones such as Plugins/GameFeatures/<Plugin>. A module counts when its <Module>.Build.cs exists; CodeForge's own modules are never targets. It always writes headers to Public/ and sources to Private/, including for modules that keep their files flat, because UnrealBuildTool only adds Public/ to the include path. The .cpp includes its header by its path under Public/ ("Arena/ArenaTurret.h").
24 Arena Sample
A small target-range game in which all 16 gameplay types are CodeForge output: game mode, player controller, HUD, turrets, colour-coded targets, pickups, a replicated health component, a damage interface, a score subsystem with save game, a Data Table row, a bitflags enum and a function library. Definitions: Samples/Arena/Arena.codeforge.json.
- In the CodeForge project: open the default map and press Play. Fire with the left mouse button or Space. Console:
ArenaSpawn 5,ArenaKillAll,ArenaAddScore 100. - In your project: Tools → CodeForge → Import Sample Pack (retargets to your module), then Generate C++ and build.
- The automation test
CodeForge.Sample.ArenaPlaysplays the map and checks that targets spawn and kills are scored.
25 Verification
CodeForge's own suite (Automation RunTests CodeForge) covers the data model, validation, templates, generator output, JSON round-trips, commandlet, Python library, graph sync and auto-fix, the wizard archetypes, UI smoke tests and a PIE run of the sample. Scripts/Verify-GeneratedCode.ps1 additionally emits every test definition, every archetype and the whole sample into a scratch project and compiles it with UnrealBuildTool.
26 Troubleshooting
A hand-written file has the same name. Rename the type or the sub-folder, or confirm the overwrite (commandlet: -Overwrite). CodeForge recognises its files by the marker in the first lines.
The definition's module isn't in this project (common after importing a JSON file from another project). Set Module Target to one of your modules; Import Sample Pack does this automatically.
New types and changed reflection need a rebuild. Live Coding can't always add a class to a running editor, so close the editor and build, or accept the restart prompt.
Set the property's Include Path (for example Components/StaticMeshComponent.h) or add the header under Source Includes. Interfaces implemented by a class are included automatically; other types need their header listed.
CodeForge v0.5.0 · Unreal Engine 5.5–5.8
Copyright © 2026 GregOrigin. All Rights Reserved.
Toolbar icons © Pop Vectors, Iconic Panda